package com.ly.lypopupwindowdemo.downladpackage;

import android.os.AsyncTask;
import android.os.Environment;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * Created by liying on 2017/11/28.
 * <p>
 * AsyncTask是一个抽象类，如果想要使用它的话，需要创建一个子类去继承它。
 * 继承时候，需要执行三个参数。
 * <p>
 * Params:在执行AsyncTask时需要传入的 参数 。可用于在后台任务中使用。
 * Progress:后台执行任务时，如果需要在界面上显示进度，这里指定的泛型作为进度的单位。
 * Result:当任务执行完之后，如果需要对结果进行返回，那么这里指定的泛型作为返回值的类型。
 * <p>
 * 比如AsyncTask<void,Integer,boolean>
 * 表示在执行AsyncTask时候不需要传入参数给后台，
 * 用整型类型数据来作为进度显示单位，
 * 使用布尔型数据来反馈执行结果。
 */

public class DownlaodTask extends AsyncTask<String, Integer, Integer> {

    public static final int TYPE_SUCCESS = 0;
    public static final int TYPE_FAILER = 1;
    public static final int TYPE_PAUSE = 2;
    public static final int TYPE_CANCLE = 4;

    private DownloadListener listener;
    private boolean isCancle;
    private boolean isPause;

    private int lastProgress;

    public DownlaodTask(DownloadListener listener) {
        this.listener = listener;
    }

    /**
     * 下载前执行
     */
    @Override
    protected void onPreExecute() {
        super.onPreExecute();

    }

    /**
     * 在后台下载执行
     *
     * @param params
     * @return
     */
    @Override
    protected Integer doInBackground(String... params) {
        InputStream is = null;
        RandomAccessFile savedFile = null;
        File file = null;

        try {
            long downloadLength = 0;//记录已下载的文件长度
            String downloadUrl = params[0];
            // String filename = downloadUrl.substring(downloadUrl.lastIndexOf("/"));
            String filename = "yfjr";
            String directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();
            file = new File(directory + filename);

            if (file.exists()) {
                downloadLength = file.length();
            }
            long contentLength = getContentLength(downloadUrl);

            if (contentLength == 0) {
                return TYPE_FAILER;
            } else if (contentLength == downloadLength) {
                return TYPE_SUCCESS;
            }

            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder()
                    //断点下载执行从哪个字节开始下载
                    .addHeader("RANGE", "bytes=" + downloadLength + "-")
                    .url(downloadUrl)
                    .build();

            Response response = client.newCall(request).execute();

            if (response != null) {
                is = response.body().byteStream();
                savedFile = new RandomAccessFile(file, "rw");
                savedFile.seek(downloadLength);//跳过已下载过的字节
                byte[] b = new byte[1024];
                int total = 0;
                int len;
                while ((len = is.read(b)) != -1) {
                    if (isCancle) {
                        return TYPE_CANCLE;
                    } else if (isPause) {
                        return TYPE_PAUSE;
                    } else {
                        total += len;
                        savedFile.write(b, 0, len);
                        //计算已经下载的百分比
                        int progress = (int) ((total + downloadLength) * 100 / contentLength);
                        publishProgress(progress);
                    }
                }

                response.body().close();
                return TYPE_SUCCESS;
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {

            try {
                if (is != null) {
                    is.close();
                }

                if (savedFile != null) {
                    savedFile.close();
                }
                if (isCancelled() && file != null) {
                    file.delete();
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
        }


        return TYPE_FAILER;
    }


    /**
     * 获取文件长度
     *
     * @return
     */
    private long getContentLength(String url) throws IOException {

        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(url)
                .build();
        Response response = client.newCall(request).execute();
        if (response != null && response.isSuccessful()) {
            long contentLength = response.body().contentLength();
            response.close();
            return contentLength;
        }

        return 0;
    }

    /**
     * 显示进度执行
     *
     * @param values
     */
    @Override
    protected void onProgressUpdate(Integer... values) {
        int progress = values[0];
        if (progress > lastProgress) {
            listener.onProgress(progress);
            lastProgress=progress;
        }

    }

    /**
     * 任务结束执行
     *
     * @param integer
     */
    @Override
    protected void onPostExecute(Integer integer) {


    }
}
